﻿using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using System.Collections;
using static CyberU.UI;
using static CyberU;

/// <summary>
/// 合并版点击处理器（同时支持单击/双击，左键/右键）
/// </summary>
public class Clicker : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler
{
    [System.Serializable] public class MouseEvent : UnityEvent { }
    [System.Serializable] public class MouseEventWithData : UnityEvent<PointerEventData> { }

    public MouseEvent onClick = new MouseEvent();
    public MouseEventWithData onClickWithEvent = new MouseEventWithData();
    public MouseEvent onLeftClick = new MouseEvent();
    public MouseEventWithData onLeftClickWithEvent = new MouseEventWithData();
    public MouseEvent onRightClick = new MouseEvent();
    public MouseEventWithData onRightClickWithEvent = new MouseEventWithData();

    // 双击事件
    public MouseEvent onDoubleClick = new MouseEvent();
    public MouseEventWithData onDoubleClickWithEvent = new MouseEventWithData();
    public MouseEvent onLeftDoubleClick = new MouseEvent();
    public MouseEventWithData onLeftDoubleClickWithEvent = new MouseEventWithData();
    public MouseEvent onRightDoubleClick = new MouseEvent();
    public MouseEventWithData onRightDoubleClickWithEvent = new MouseEventWithData();

    // ======== 参数设置 ========
    [Tooltip("两次点击的最大间隔时间（秒）")]
    public float maxDoubleClickTime = 0.3f;

    [Tooltip("点击允许的最大移动距离（像素）")]
    public float maxMoveDistance = 10f;

    // ======== 运行时状态 ========
    private int clickCount = 0;
    private float lastClickTime;
    private Vector2 lastClickPosition;
    private bool isDragging;
    private PointerEventData currentEventData;

    // ======== Unity事件接口 ========
    public void OnPointerDown(PointerEventData eventData)
    {
        isDragging = false;
        currentEventData = eventData;
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        if (isDragging) return;

        float currentTime = Time.unscaledTime;
        float distance = Vector2.Distance(eventData.position, lastClickPosition);

        // 双击判定：时间间隔和移动距离均符合要求
        if (clickCount > 0 && 
            currentTime - lastClickTime <= maxDoubleClickTime && 
            distance <= maxMoveDistance)
        {
            clickCount++;
        }
        else
        {
            clickCount = 1; // 重置计数
        }

        lastClickTime = currentTime;
        lastClickPosition = eventData.position;
        currentEventData = eventData;
        if (clickCount == 2)
        {
            TriggerDoubleClick(eventData);
            clickCount = 0; // 重置
            CancelInvoke(nameof(TriggerClick)); // 取消待触发的单击
        }
        else if (clickCount == 1)
        {
            StartCoroutine(DelayedClickCheck(eventData));
        }
    }

    public void OnDrag(PointerEventData eventData) => isDragging = true;
    private IEnumerator DelayedClickCheck(PointerEventData eventData)
    {
        yield return new WaitForSeconds(maxDoubleClickTime + 0.05f); // 稍长于双击间隔
        if (clickCount == 1) // 期间没有第二次点击
        {
            TriggerClick(eventData);
            clickCount = 0;
        }
    }

    private void TriggerClick(PointerEventData eventData)
    {
        onClick.Invoke();
        onClickWithEvent.Invoke(eventData);
        if (eventData.button == PointerEventData.InputButton.Left)
        {
            onLeftClick.Invoke();
            onLeftClickWithEvent.Invoke(eventData);
        }
        else if (eventData.button == PointerEventData.InputButton.Right)
        {
            onRightClick.Invoke();
            onRightClickWithEvent.Invoke(eventData);
        }
    }

    private void TriggerDoubleClick(PointerEventData eventData)
    {
        // Delog("Double Click!");
        onDoubleClick.Invoke();
        onDoubleClickWithEvent.Invoke(eventData);
        if (eventData.button == PointerEventData.InputButton.Left)
        {
            onLeftDoubleClick.Invoke();
            onLeftDoubleClickWithEvent.Invoke(eventData);
        }
        else if (eventData.button == PointerEventData.InputButton.Right)
        {
            onRightDoubleClick.Invoke();
            onRightDoubleClickWithEvent.Invoke(eventData);
        }
    }
    public void Add(UnityAction action) => onClick.AddListener(action);
    public void Add(UnityAction<PointerEventData> action) => onClickWithEvent.AddListener(action);
    public void AddLeft(UnityAction action) => onLeftClick.AddListener(action);
    public void AddLeft(UnityAction<PointerEventData> action) => onLeftClickWithEvent.AddListener(action);
    public void AddRight(UnityAction action) => onRightClick.AddListener(action);
    public void AddRight(UnityAction<PointerEventData> action) => onRightClickWithEvent.AddListener(action);

    public void AddDouble(UnityAction action) => onDoubleClick.AddListener(action);
    public void AddDouble(UnityAction<PointerEventData> action) => onDoubleClickWithEvent.AddListener(action);
    public void AddLeftDouble(UnityAction action) => onLeftDoubleClick.AddListener(action);
    public void AddLeftDouble(UnityAction<PointerEventData> action) => onLeftDoubleClickWithEvent.AddListener(action);
    public void AddRightDoubleClick(UnityAction action) => onRightDoubleClick.AddListener(action);
    public void AddRightDoubleClick(UnityAction<PointerEventData> action) => onRightDoubleClickWithEvent.AddListener(action);
}